package com.jhh.pay.center.api;

import com.jhh.pay.center.actor.ActorUtil;
import com.jhh.pay.center.actor.DeferredCompleteFunctional;
import com.jhh.pay.center.api.data.NotifyRequest;
import com.jhh.pay.center.api.data.Result;
import com.jhh.pay.center.model.TradeState;
import com.jhh.pay.center.service.cloud.message.TradeResult;
import com.jhh.pay.center.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;

/**
 * @author tangxd
 * @Description: TODO
 * @date 2017/12/14
 */
@RestController
@RequestMapping("jhhpay/notify")
@Slf4j
public class NotifyController extends AbstractController {

    @RequestMapping(value = "/{name}", method = {RequestMethod.POST, RequestMethod.GET})
    DeferredResult<Object> notify(
            @PathVariable("name") String name,
            HttpServletRequest req
    ) {
        NotifyRequest notify = new NotifyRequest();
        if (req.getMethod().toLowerCase().equals("post")) {
            try {
                notify.setBody(getRequestPostStr(req));
                notify.setChannelName(name);
            } catch (Exception e) {
                e.printStackTrace();
                log.error("解析通知信息失败,格式错误", e);
            }
        }
        if (req.getMethod().toLowerCase().equals("get")) {
            notify.setBody(req.getQueryString());
            notify.setChannelName(name);
        }
        DeferredResult<Object> result = ActorUtil.deferred(
                "CallbackResolveActor",
                "resolve-actor-" + StringUtils.random(10),
                notify,
                config.getActorProcessTimeout(),
                (DeferredCompleteFunctional<TradeResult, Object>) (failure, response, r) -> {
                    if (response != null) {
                        r.setResult(response);
                    } else {
                        r.setErrorResult(new Result(TradeState.ERROR, null, "SYS:TIMEOUT", "处理超时"));
                    }
                });
        return result;
    }

    private static String getRequestPostStr(HttpServletRequest request)
            throws IOException {
        byte[] buffer = getRequestPostBytes(request);
        String charEncoding = request.getCharacterEncoding();
        if (charEncoding == null) {
            charEncoding = "UTF-8";
        }
        return new String(buffer, charEncoding);
    }

    private static byte[] getRequestPostBytes(HttpServletRequest request)
            throws IOException {
        int contentLength = request.getContentLength();
        if (contentLength < 0) {
            return null;
        }
        byte buffer[] = new byte[contentLength];
        for (int i = 0; i < contentLength; ) {

            int readlen = request.getInputStream().read(buffer, i, contentLength - i);
            if (readlen == -1) {
                break;
            }
            i += readlen;
        }
        return buffer;
    }
}
